//
// Created by wsl on 2024/3/1.
//

#include "LinkList.h"

DataStructure_Warning_Unused
static LinkList_Node LinkList_CreateNode(T e, size_t dataSize) {
	if (NULL == e)
		return NULL;

	//创建节点
	LinkList_Node newNode = (LinkList_Node) DataStructure_AllocT(LinkList_N);
	if (NULL == newNode) {
		//内存分配失败，调用溢出处理函数
		DataStructure_Overflow_Handler();
		return NULL;                //兜底
	}

	//创建数据域
	T data = DataStructure_AllocT(dataSize);
	if (NULL == data) {
		DataStructure_MemoryFree(newNode);
		DataStructure_Overflow_Handler();
		return NULL;
	}

	//为数据域赋值
	DataStructure_MemoryCpy(data, e, dataSize);

	//初始化节点
	newNode->data = data;
	newNode->next = NULL;

	return newNode;
}

DataStructure_Warning_Unused
static void *LinkList_Get(LinkList list, int index) {
	LinkList_Node curNode = list->firstElem;
	//记录头节点
	while (curNode && --index) {
		curNode = curNode->next;
	}

	return curNode->data;
}

//清除所有节点，但不清除头节点
DataStructure_Warning_Unused
Status LinkList_clear(LinkList list) {
	if (NULL == list)
		return OVERFLOW;

	//首元节点为空，无节点
	if (LinkList_isEmpty(list))
		return TRUE;

	//获取到头节点
	LinkList_Node curNode = list->firstElem;
	LinkList_Node temp = NULL;

	while (curNode) {
		temp = curNode;                    //记录需释放的节点
		DataStructure_MemoryFree(temp->data);                //释放数据域
		curNode = curNode->next;        //当前节点后移
		DataStructure_MemoryFree(temp);                        //释放节点本身
		list->length--;
	}

	//list->elem = NULL;
	list->firstElem = NULL;
	list->endElem = NULL;

	return TRUE;
}

DataStructure_Warning_Unused
int LinkList_length(LinkList list) {
	if (NULL == list)
		return -1;

	return list->length;
}

//释放所有节点，释放头节点，释放对象本身
DataStructure_Warning_Unused
Status LinkList_destroy(LinkList *list) {
	if (NULL == list || NULL == *list)
		return FALSE;

	//释放所有节点
	if (LinkList_isEmpty(*list) == FALSE)
		LinkList_clear(*list);

	//释放头节点
	DataStructure_MemoryFree((*list)->head);
	//释放链表对象
	DataStructure_MemoryFree(*list);

	//置空
	*list = NULL;

	return TRUE;

}

DataStructure_Warning_Unused
LinkList LinkList_create(size_t dataSize) {
//	if(NULL == list)
//		return FALSE;
//
//	if (NULL != *list)
//		LinkList_destroy(list);

	//创建链表
	LinkList tempLinkList = (LinkList) DataStructure_AllocT(LL);
	if (NULL == tempLinkList) {
		DataStructure_Overflow_Handler();
		return NULL;
	}

	//创建头节点
	LinkList_Node tempLinkListNode = (LinkList_Node) DataStructure_AllocT(LinkList_N);
	if (NULL == tempLinkListNode) {
		DataStructure_MemoryFree(tempLinkList);
		DataStructure_Overflow_Handler();
		return NULL;
	}

	//初始化节点
	tempLinkListNode->data = NULL;            //头节点数据域不存放数据
	tempLinkListNode->next = NULL;            //单向链表


	//初始化各项属性
	tempLinkList->head = tempLinkListNode;    //指向头节点
	tempLinkList->firstElem = NULL;                //指向首元节点用，因此置空
	tempLinkList->endElem = NULL;                //指向尾元节点用，因此置空
	tempLinkList->length = 0;
	tempLinkList->dataSize = dataSize;

	//返回对象
	return tempLinkList;
}

DataStructure_Warning_Unused
Status LinkList_isEmpty(LinkList list) {
	if (NULL == list)
		return FALSE;

	return list->length <= 0 ? TRUE : FALSE;
}

DataStructure_Warning_Unused
Status LinkList_at(LinkList list, int index, T buf) {
	if (NULL == list || index < 1 || index > list->length)
		return FALSE;

	if (LinkList_isEmpty(list))
		return FALSE;

	//将数据拷贝到缓冲区中
	DataStructure_GetValue(buf, LinkList_Get(list, index), list->dataSize);

	return TRUE;
}

DataStructure_Warning_Unused
Status LinkList_add(LinkList list, T e) {
	if (NULL == list || NULL == e || NULL == list->head)
		return FALSE;

	//创建节点
	LinkList_Node node = LinkList_CreateNode(e, list->dataSize);
	if (NULL == node)
		return FALSE;

	LinkList_Node head = list->head;        //头节点
	//尾插入
	if (LinkList_isEmpty(list))                //空表
	{
		head->next = node;                    	//挂载到头节点后
		list->firstElem = node;                 //标记为首元节点
	}
	else {
		//挂载到尾元节点后
		list->endElem->next = node;
	}

	list->endElem = node;            //更新尾元节点
	//数量更新
	list->length++;

	return TRUE;
}

DataStructure_Warning_Unused
Status LinkList_header(LinkList list, T e) {
	if (LinkList_isEmpty(list)) {        //无节点，直接尾插入
		LinkList_add(list, e);
	}
	else                                //有节点
	{
		LinkList_Node newNode = LinkList_CreateNode(e, list->dataSize);
		if (NULL == newNode)
			return FALSE;

		newNode->next = list->head->next;
		list->head->next = newNode;

		//更新首元节点
		list->firstElem = newNode;
		list->length++;
	}

	return TRUE;
}

DataStructure_Warning_Unused
Status LinList_insert(LinkList list, T e, int index) {
	if (NULL == list || index < 1)
		return FALSE;

	if (index == 1)                            //插入到表头，作为首元节点
	{
		LinkList_header(list, e);
	}
	else if (index > list->length)            //大于链表长度，直接插入到链表尾部
	{
		LinkList_add(list, e);
	}
	else {
		LinkList_Node newNode = LinkList_CreateNode(e, list->dataSize);
		if (NULL == newNode)
			return FALSE;

		LinkList_Node curNode = list->firstElem;
		LinkList_Node pre = NULL;

		//找到目标位置
		while (--index) {
			pre = curNode;
			curNode = curNode->next;
		}

		//链接
		newNode->next = curNode;
		pre->next = newNode;

		//更新数量
		list->length++;
	}

	return TRUE;
}

DataStructure_Warning_Unused
Status LinkList_removeHeader(LinkList list, T buf) {
	if (NULL == list || NULL == buf)
		return FALSE;

	if (LinkList_isEmpty(list))        //空表
		return FALSE;

	//记录首元节点
	LinkList_Node temp = list->firstElem;
	//链接
	list->head->next = temp->next;

	//更新首尾元节点
	list->firstElem = list->head->next;
	//释放的节点同时是尾元节点，则目前表中只有一个节点
	(temp == list->endElem) ? (list->endElem = list->head->next) : 0;

	DataStructure_MemoryCpy(buf, temp->data, list->dataSize);

	//释放首元节点的数据域
	DataStructure_MemoryFree(temp->data);
	//释放旧首元节点
	DataStructure_MemoryFree(temp);


	//更新数量
	list->length--;

	return TRUE;
}

DataStructure_Warning_Unused
Status LinkList_remove(LinkList list, int index, T buf) {
	if (NULL == list || NULL == buf || index < 1 || index > list->length)
		return FALSE;

	if (LinkList_isEmpty(list))
		return FALSE;

	//释放的是首元节点
	if (index == 1) {
		LinkList_removeHeader(list, buf);
	}
	else {
		LinkList_Node curNode = list->firstElem;
		LinkList_Node pre = NULL;
		LinkList_Node temp = NULL;

		//找到目标位置
		while (--index) {
			pre = curNode;
			curNode = curNode->next;
		}
		//记录目标节点
		temp = curNode;
		//链接
		pre->next = temp->next;
		//释放的节点同时是尾元节点，则目前表中只有一个节点
		(temp == list->endElem) ? (list->endElem = pre) : 0;

		DataStructure_MemoryCpy(buf, temp->data, list->dataSize);

		//释放目标节点数据域
		DataStructure_MemoryFree(temp->data);
		//释放目标节点
		DataStructure_MemoryFree(temp);

		//更新数量
		list->length--;
	}

	return TRUE;
}

DataStructure_Warning_Unused
int LinkList_equalsFind(LinkList list, T e, char (*equals)(T e, T b)) {
	if (NULL == list || NULL == e || NULL == equals || LinkList_isEmpty(list))
		return 0;

	int i = 1;
	LinkList_Node curNode = list->firstElem;
	while (curNode) {
		if (equals(e, curNode->data) == 1) {
			return i;
		}

		curNode = curNode->next;
		i++;
	}

	return 0;
}

DataStructure_Warning_Unused
void LinkList_traversal(LinkList list, void(*look)(T e)) {
	if (NULL == list || NULL == look || FALSE != LinkList_isEmpty(list))
		return;

	//遍历链表
	LinkList_Node header = list->firstElem;
	while (1) {
		look(header->data);

		if (header == list->endElem)
			break;

		header = header->next;
	}
}

//会释放对象list2和list2的头节点。
DataStructure_Warning_Unused
Status LinkList_connect(LinkList list1, LinkList *list2) {
	if (NULL == list1 || NULL == list2)
		return FALSE;

	//空表不进行链接
	if (LinkList_isEmpty(list1) == TRUE || LinkList_isEmpty(*list2) == TRUE)
		return FALSE;

	//数据域是否一样（此处只检测大小，不检查类型，需要用户自己注意）
	if (list1->dataSize != (*list2)->dataSize)
		return FALSE;

	//获取链表1的尾指针，链表2的头指针
	LinkList_Node lis1_end = list1->endElem;
	LinkList_Node lis2_header = (*list2)->firstElem;

	//链接
	lis1_end->next = lis2_header;


	//更新链表1的尾指针
	list1->endElem = (*list2)->endElem;

	//更新数量
	list1->length += (*list2)->length;

	//销毁list2
	DataStructure_MemoryFree((*list2)->head);
	DataStructure_MemoryFree(*list2);

	*list2 = NULL;

	return TRUE;
}

DataStructure_Warning_Unused
Status LinkList_replace(LinkList list, T e, int index) {
	if (NULL == list || NULL == e || index < 1 || index > list->length)
		return FALSE;

	//找到索引对应的节点
	LinkList_Node node = LinkList_Get(list, index);

	//拷贝数据
	DataStructure_MemoryCpy(node, e, list->dataSize);

	return TRUE;
}

DataStructure_Warning_Unused
Status LinkList_reverse(LinkList *list) {
	if (NULL == list)
		return FALSE;

	if (LinkList_isEmpty(*list) != FALSE || 1 == LinkList_length(*list))
		return FALSE;

	//获取到链表头
	LinkList oldList = *list;


	LinkList newList = NULL;
	newList = LinkList_create((*list)->dataSize);

	LinkList_Node head = oldList->firstElem;

	while (head) {
		LinkList_header(newList, head->data);
		head = head->next;
	}

	*list = newList;

	//销毁旧链表
	LinkList_destroy(&oldList);

	return TRUE;
}


